package com.clp.protocol.iec104;

import com.clp.protocol.core.common.async.IFutureListener;
import com.clp.protocol.iec104.client.Iec104Client;
import com.clp.protocol.iec104.client.Master;
import com.clp.protocol.iec104.client.async.ClientFuture;
import com.clp.protocol.iec104.client.async.MasterFuture;
import com.clp.protocol.iec104.client.async.MasterFutureListener;
import com.clp.protocol.iec104.client.async.send_apdu.SendTcExecuteRes;
import com.clp.protocol.iec104.client.async.send_apdu.SendTcSelectRes;
import com.clp.protocol.iec104.client.master_config.MasterConnConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * 当前版本 V1.1
 *      - 基于 netty，多子站连接管理，断线自动重连
 *      - 全异步操作
 *      - 支持单点、双点遥信数据采集
 *      - 支持归一化值、短浮点数、标度化值遥测数据采集
 *      - 支持单点、双点遥控命令下发
 *      - 支持遥调
 *      - ui 监控面板生成
 */

@Slf4j
public class HowToUse {
    /**
     *  已实现基本的遥信、遥测的采集；单点、双点遥控；遥调
     *
     * @param args
     * @throws InterruptedException
     * @throws IOException
     */
    public static void main(String[] args) throws InterruptedException, IOException {
        // 1、获取客户端
        Iec104Client iec104Client = Iec104Client.get();
        // 2、新建连接，返回的future类似netty的ChannelFuture，只不过这个是关联的主站Master
        MasterFuture<Void> masterConnFuture = iec104Client.connect(
                MasterConnConfig.configurer()
                        .connection("127.0.0.1", 2404) // 连接的子站ip
                        .rtuAddr(1) // 公共地址
                        .autoStartDtV(true) // 是否自动启动传输激活
                        .totalCall100PeriodSeconds(60) // 设置总召唤周期
                        .t0t1t2t3(6, 3, 2, 4) // t0, t1, t2 ,t3 ，如果时间过长会有channel自动断开的问题
                        .configOk()
        );

        // 同步或异步等待连接结果
        // 同步等待 : masterConnFuture.sync();
        // 异步等待
        masterConnFuture.addListener(new MasterFutureListener<Void>() {
            @Override
            public void operationComplete(MasterFuture<Void> future) {
                if (future.isSuccess()) {
                    log.info("连接成功！");
                    // 获取主站发送一些报文
                    future.master().sendUApduOfTestFrV();
                } else {
                    log.info("连接失败！");
                }
            }
        }).sync();

        // 可以从客户端或者MasterFuture中获取主站
        Master master1 = Iec104Client.get().getMaster("127.0.0.1", 2404);
        Master master2 = masterConnFuture.master();
        log.info("{}", master1 == master2);

//        master1.sendIApduOfTotalCall100();// 主动发送总召唤
//        master1.sendSApduOfAck(); // 主动发送S帧
//        master1.sendUApduOfStartDtV(); // 主动发送启动传输激活
//        master1.sendUApduOfTestFrV(); // 主动发送链路测试激活
//        master1.sendUApduOfTestFrC(); // 主动发送链路测试确认

//        // 添加回调
//        master1.addRecvApduCallback(new RecvApduCallback() {
//            @Override
//            public boolean whenRecvApdu(Apdu apdu) {
//                log.info("接收到了apdu，执行回调...");
//                return false; // 每次接收到apdu都会执行
//            }
//        });

//        // 查看master状态
//        new Thread(() -> {
//            int count = 0;
//            while(++count < 100) {
//                try {
//                    Thread.sleep(1000 * 2);
//
//                    log.info("isConnected: " + master1.isConnected());
//                    log.info("isDoingTotalCall100: " + master1.isDoingTotalCall100());
//                    log.info("isStartedDt: " + master1.isStartedDt());
//                    log.info("isRecvedInitEnd: " + master1.isRecvedInitEnd());
//                    log.info("");
//
//                    master1.sendIApduOfTotalCall100();
//
//                    log.info("isConnected: " + master1.isConnected());
//                    log.info("isDoingTotalCall100: " + master1.isDoingTotalCall100());
//                    log.info("isStartedDt: " + master1.isStartedDt());
//                    log.info("isRecvedInitEnd: " + master1.isRecvedInitEnd());
//                    log.info("");
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        });

        Thread.sleep(1000 * 1);
        if (master1.stateInfo().isRecvedInitEnd()) {
            master1.sendIApduOfOnePointTcSelect(24578, true).addListener(new MasterFutureListener<SendTcSelectRes>() {
                @Override
                public void operationComplete(MasterFuture<SendTcSelectRes> future) {
                    if (future.isSuccess()) {
                        log.info("遥控选择成功！");
                        future.master().sendIApduOfOnePointTcExecute(24578, true).addListener(new MasterFutureListener<SendTcExecuteRes>() {
                            @Override
                            public void operationComplete(MasterFuture<SendTcExecuteRes> future) {
                                if (future.isSuccess()) {
                                    log.info("遥控执行成功！");
                                } else {
                                    log.warn("遥控执行失败！");
                                }
                            }
                        });
                    } else {
                        log.warn("遥控选择失败！");
                    }
                }
            });
        }

        // 尝试运行1分钟
        Thread.sleep(1000 * 60);

        // 结束
        iec104Client.disconnectAll().addListener(new IFutureListener<ClientFuture<Void>>() {
            @Override
            public void operationComplete(ClientFuture<Void> future) {
                if (future.isSuccess()) {
                    log.info("断开成功！");
                } else {
                    log.info("断开失败！");
                }
            }
        });
        iec104Client.close();
    }
}
